package com.ruoyi.web.controller.utils;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.ObjectMetadata;
import com.ruoyi.document.domain.Contract;
import com.ruoyi.document.service.impl.ContractServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.UUID;

/**
 * @author : 张培浩
 * @date : 2022/12/12 20:33
 **/
@RestController
@RequestMapping("/image")
public class ImageController {
    @Autowired
    private ContractServiceImpl contractService;

    @Value("${aliyun.oss.endpoint}")
    public   String ALIYUN_OSS_ENDPOINT;
    @Value("${aliyun.oss.accessKeyId}")
    public   String ALIYUN_OSS_ACCESSKEYID;
    @Value("${aliyun.oss.accessKeySecret}")
    public   String ALIYUN_OSS_ACCESSKEYSECRET;
    @Value("${aliyun.oss.bucketName}")
    public  String ALIYUN_OSS_BUCKETNAME;

    /**
     * 上传文件保存到本地文件夹
     * 给到前端前端再次发送请求添加数据保存到数据库
     * @param file
     * @return
     *
     */
    @PostMapping("/upload")
    public String upload(MultipartFile file){
        String baseImg = "C:/uploads/jh/";
        String originalFilename = file.getOriginalFilename();
        String substring = originalFilename.substring(originalFilename.lastIndexOf("."));
        String fileName = UUID.randomUUID().toString().replace("-", "")+substring;
        File file1 = new File(baseImg+fileName);
        if (!file1.exists()){
            file1.mkdirs();
        }
        try {
            file.transferTo(file1);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //需要返回图片名称信息数据库需要保存图片名称数据
        return fileName;
    }
    /**
     * 下载图片 / 加载本地图片资源
     * @param name
     * @param response
     */
    @GetMapping("/download")
    public void download(String name , HttpServletResponse response){
        String baseImg = "C:/uploads/jh/";
        try {
            //第一步读取本地文件
            FileInputStream fileInputStream = new FileInputStream(new File(baseImg+name));
            // 第二步响应给页面
            ServletOutputStream outputStream = response.getOutputStream();
            // 设置响应编码类型
            response.setContentType("image/jpeg");
            int len = 0;
            byte[] bytes = new byte[1024];
            while ((len = fileInputStream.read(bytes)) != -1){
                outputStream.write(bytes,0,len);
            }
            // 关闭流
            outputStream.close();
            fileInputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 实现阿里云oss文件存储的远程上传图片
     * @param file
     * @return
     * @throws IOException
     */
    @PostMapping("/aLiYunImage")
    public String aLiYunImage(MultipartFile file) throws IOException {
        // 自定义时间格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        // 创建OSSClientBuilder对象  填入对应的域名 accessKeyId   accessKeySecret
        OSSClientBuilder ossClientBuilder = new OSSClientBuilder() ;
        OSS oss = ossClientBuilder.build(ALIYUN_OSS_ENDPOINT, ALIYUN_OSS_ACCESSKEYID, ALIYUN_OSS_ACCESSKEYSECRET);
        // 获取文件名称
        String filename = file.getOriginalFilename();
        // 获取文件后缀名
        String type = filename.substring(filename.lastIndexOf("."));
        // 最后上传生成的文件名
        String finalFileName = System.currentTimeMillis() + "" + new SecureRandom().nextInt(0x0400) + type;
        // oss中的文件夹名  当前时间yyyyMMdd/finalFileName
        String objectName = sdf.format(new Date()) + "/" + finalFileName;
        // 创建上传文件的元信息，可以通过文件元信息设置HTTP header(设置了才能通过返回的链接直接访问)。
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setContentType("image/jpg");
        // 文件上传
        oss.putObject(ALIYUN_OSS_BUCKETNAME, objectName, new ByteArrayInputStream(file.getBytes()),objectMetadata);
        // 设置URL过期时间为1小时。
        Date expiration = new Date(System.currentTimeMillis() + 3600 * 1000);
        // 获取上传后的请求地址通过bucket名称  文件的保存路径  请求地址的过期时间
        String url = oss.generatePresignedUrl(ALIYUN_OSS_BUCKETNAME, objectName, expiration).toString();
        System.out.println("阿里云文件中的路径信息:"+url);
        return url;
    }

    /**
     * 实现文件上传到fastDFS中
     * @param file
     * @return 参数1: 组名 参数2: 文件名 参数3: 文件类型 参数4: 文件大小 参数5: 旧文件的名称
     * @throws IOException
     */
    @PostMapping("/uploadFastDFS")
    public Contract uploadFastDFS(MultipartFile file) throws IOException {
        // 获取上传文件的字节信息
        byte[] buffFile = file.getBytes();
        // 获取当前文件的类型
        String fileExtName = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
        // 调用fastDFS 上传文件方法
        String[] result = fastDFSUtils.upload(buffFile, fileExtName);
        Contract contract = new Contract();
        contract.setGroupName(result[0]);
        contract.setFileName(result[1]);
        contract.setFileType(fileExtName);
        contract.setFileSize(file.getSize());
        contract.setOldFileName(file.getOriginalFilename());
        System.out.println(Arrays.toString(result));
        return contract;
    }

    @GetMapping("/downloadShowFastDFS")
    public void downloadShowFastDFS(String groupName,String fileName,HttpServletResponse response) throws IOException {
        // 调用工具类实现文件的下载
        byte[] fileBytes = fastDFSUtils.download(groupName, fileName);
        // 设置浏览器响应格式
        response.setContentType("image/jpeg");
        // 响应到浏览器
        ServletOutputStream outputStream = response.getOutputStream();
        outputStream.write(fileBytes);
        // 关闭流
        outputStream.close();
    }


    @GetMapping("/downloadFastDFS")
    public ResponseEntity<byte[]> downloadFastDFS(String groupName,String fileName,long fileSize, String oldFileName){
        // 获取下载文件的字节数组
        byte[] bytes = fastDFSUtils.download(groupName, fileName);
        HttpHeaders headers = new HttpHeaders();
        // 设置响应类型为文件类型
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        // 设置响应是的文件大小
        headers.setContentLength(fileSize);
        // 设置下载时的默认文件名
        headers.setContentDispositionFormData("attachment",oldFileName);
        /**
         * 创建响应实体对象,Spring会将这个对象返回给浏览器 ,作为响应数据
         * 参数1  为响应时的具体数据
         * 参数2 为响应时的头信息
         * 参数3 为响应时的状态码
         */
        ResponseEntity<byte[]> responseEntity = new ResponseEntity<byte[]>(bytes,headers, HttpStatus.OK);
        return responseEntity;
    }

}
